package gggameserver.testbed;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;

import net.schmizz.sshj.connection.channel.direct.Session.Command;

import gggameserver.compiler.GGCompiler;
import gggameserver.exceptions.GGProcessException;
import gggameserver.exceptions.GGTimeout;
import gggameserver.games.connection.GGConnection;
import gggameserver.util.GGUtil;

public class GGMirroredConnection implements GGConnection, Runnable {

	GGMirroredTestBed tb;
	private GGMirror mirror;
	private BufferedReader in;
	private PrintWriter out;
	private BufferedReader inStdErr;
	private Thread stderrThread;
	
	public GGMirroredConnection(GGMirroredTestBed ggMirroredTestBed, boolean runOnly) {
		init(ggMirroredTestBed, runOnly);
	}
	
	public GGMirroredConnection(GGMirroredTestBed ggMirroredTestBed) {
		init(ggMirroredTestBed, false);
	}
	
	private void init(GGMirroredTestBed ggMirroredTestBed, boolean runOnly) { 
		tb = ggMirroredTestBed;
		if (!tb.isValid()) { 
			throw new IllegalStateException("Testbed is not valid\n\nLog:\n\n" + ggMirroredTestBed.getLog());
		}
		
		mirror = tb.m_tbf.getMirror("test" + tb.m_nr);

		if (!mirror.connect()) throw new IllegalStateException("Couldn't connect to mirrored testbed");

		ArrayList<String> cmd;

if (!runOnly) {
		cmd = tb.getCDCmd(mirror.getTestBedPath());
		cmd.add("rm");
		cmd.add("-rf");
		cmd.add("*");
		cmd.add(tb.m_compiledZip.getName()); // TODO is it neccessary?
		if (!mirror.execute(GGUtil.toCmdline(cmd))) 
			throw new IllegalStateException("Couldn't clean testbed");
		
//		cmd = tb.getCDCmd(mirror.getTestBedPath());
//		cmd.add("cp");
//		cmd.add("../data/" + tb.m_compiledZip.getName());
//		cmd.add(".");
//		if (!mirror.execute(GGUtil.toCmdline(cmd))) 
//			throw new IllegalStateException("Couldn't copy zipped file");
		if (!mirror.copyToMirror(tb.m_compiledZip, ".")) {
		    throw new IllegalStateException("Couldn't copy zipped file");
        }
		
		cmd = tb.getCDCmd(mirror.getTestBedPath());
		cmd.add("unzip");
		cmd.add(tb.m_compiledZip.getName());
		if (!mirror.execute(GGUtil.toCmdline(cmd))) 
			throw new IllegalStateException("Couldn't unzip");
}
		
        cmd = tb.m_commandline;
		Command command = mirror.exec(GGUtil.toCmdline(cmd));
		if (null == command)
			throw new IllegalStateException("Couldn't start command");
		
		this.in = new BufferedReader(new InputStreamReader(command.getInputStream()));
		this.inStdErr = new BufferedReader(
				new InputStreamReader(command.getErrorStream()));
		this.out = new PrintWriter(command.getOutputStream(), false);
		
		stderrThread = new Thread(this);
		stderrThread.setDaemon(true);
		stderrThread.start();
	}

	@Override
	public void sendCommand(String cmd) {
System.out.println(this + ">" + cmd);
		out.print(cmd);
		out.print('\n');
		out.flush();
	}

	private boolean firstRead = true;
	
	@Override
	public String receiveCommand(long timeout) throws GGTimeout {
System.out.println(this + "...<");
//		System.out.print(">");
		String a = null;
		try {
			a = in.readLine();
			if (firstRead && null != a && a.startsWith(
			        //"OpenJDK Server VM warning: Can't detect initial thread stack location - find_vma failed"
			        "OpenJDK 64-Bit Server VM warning: Can't detect initial thread stack location - find_vma failed"
			        )) {
				System.out.println("Skipping warning");
				a = in.readLine();
			}
System.out.println(this + "<" + a);
			firstRead = false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return a;
	}

	@Override
	public void close() {
		mirror.disconnect();
	}

	@Override
	public void run() {
		String line = null;
		try {
			while (null != (line = inStdErr.readLine())) {
				System.err.println("EEE " + line);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}
